﻿using DynamicExpresso;
using Furion.LinqBuilder;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinGetCurrentAutoReplyInfoResponse.Types.KeywordAutoReplyRule.Types;

namespace Admin.NET.Core;

public static class SqlSugarWhereIFExtension
{
    /// <summary>
    /// 列表做为条件时, 如果列表只有一个值用等式提高性能, 否则用 in 语句
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <param name="queryable"></param>
    /// <param name="list"></param>
    /// <param name="column"></param>
    /// <returns></returns>
    public static ISugarQueryable<T> WhereIFList<T, T2>(this ISugarQueryable<T> queryable, List<T2> list, string column) where T : class, new()
    {
        if (null == list || list.Count == 0 || string.IsNullOrEmpty(column))
        {
            return queryable;
        }
        Expression<Func<T, bool>> finalExpression = null;
        if (list.Count == 1)
        {
            // 只有一个值用等式提高性能
            var keyword = list[0];
            var parameter = Expression.Parameter(typeof(T), "x");
            var property = Expression.Property(parameter, column);
            var constant = Expression.Constant(keyword);
            var call = Expression.Equal(property, constant);
            var lambda = Expression.Lambda<Func<T, bool>>(call, parameter);

            if (finalExpression == null)
            {
                finalExpression = lambda;
            }
            else
            {
                finalExpression = finalExpression.Or(lambda);
            }
        }
        else
        {
            // 多个值用Contains
            var parameter = Expression.Parameter(typeof(T), "x");
            var property = Expression.Property(parameter, column);
            var method = list.GetType().GetMethod("Contains");
            var constant = Expression.Constant(list);
            var call = Expression.Call(constant, method, property);
            var lambda = Expression.Lambda<Func<T, bool>>(call, parameter);

            if (finalExpression == null)
            {
                finalExpression = lambda;
            }
            else
            {
                finalExpression = finalExpression.Or(lambda);
            }
        }

        return queryable.Where(finalExpression);
    }
}
